package Receivers

import "gitee.com/ling-bin/network/netInterface"

//JT1078Receiver JT1078分包器
type JT1078Receiver struct {
	startBf    []byte      //数据开头
	startCount int         //数据头长度
	dataLen    map[int]int //数据类型对应固定数据长度
	lenBf      int         //数据内容对应数据位数
}

//NewJT1078Receiver 按照开始结束符来粘包
func NewJT1078Receiver(startBf []byte) *JT1078Receiver {
	defaultLen := 28
	return &JT1078Receiver{
		startBf: startBf,
		dataLen: map[int]int{
			0: defaultLen,
			1: defaultLen,
			2: defaultLen,
			3: defaultLen - 4,
			4: defaultLen - 8 - 2 - 2,
		},
		startCount: len(startBf),
	}
}

//GetHeadLen 包头必须要够长度
func (j *JT1078Receiver) GetHeadLen() int {
	return 30
}

//CanHandle 是否我处理
func (j *JT1078Receiver) CanHandle(conn netInterface.IConnection, buffer []byte) bool {
	return buffer[0] == j.startBf[0] && buffer[1] == j.startBf[1] && buffer[2] == j.startBf[2] && buffer[3] == j.startBf[3]
}

//Reset 重置分包状态为初始状态
func (j *JT1078Receiver) Reset()  {
	
}

//Receiver 分包逻辑
func (j *JT1078Receiver) Receiver(conn netInterface.IConnection, buffer []byte) ([]byte, int) {
	var (
		bfLen              = len(buffer) //数据长度
		startIndex         = -1          //分包开始字节
		packageOkLen       = 0           //已处理分包的长度
		packetLen          = 0           //当前包长度
		packageStartCount  = 0           //开始分包已确认个数
		packageStartStatus = 0           //是否开始分包状态[0未开始，1开始]
	)
	for i := 0; i < bfLen; i++ {
		if packageStartStatus == 0 {
			if buffer[i] == j.startBf[packageStartCount] {
				packageStartCount++
				packageOkLen++
				if packageStartCount == j.startCount {
					packageStartStatus = 1
					startIndex = i - j.startCount + 1
				}
			} else {
				packageStartCount = 0
				packageOkLen = 0
			}
			//认开始标志
			continue
		}
		//累加收到的字节数
		packageOkLen++
		if packetLen == 0 {
			//确认当前包长度
			dataType := int(buffer[startIndex+15] >> 4 & 0x0f)
			position := startIndex + j.dataLen[dataType]
			packetLen = int(buffer[position])<<8 + int(buffer[position+1]) + j.dataLen[dataType] + 2
			if packetLen > 10240 { //获取的包长度太大则跳过重新获取分包
				packageStartCount = 0
				packageOkLen = 0
				continue
			}
			if bfLen-startIndex >= packetLen { //如果包够长则直接结束
				hData := buffer[startIndex : packetLen+startIndex]
				startIndex = packetLen + startIndex
				return hData, startIndex
			}
		}
		if packetLen != 0 && packageOkLen == packetLen {
			hData := buffer[startIndex : i+1]
			startIndex = i + 1
			return hData, startIndex
		}
	}
	return nil, startIndex
}